﻿using Docx2Epub.Docx;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Docx2Epub.Epub
{
    class EpubNavigationXhtmlWriter : WriterBase
    {
        private string navHtmlFilePath;
        private IEnumerable<DocElement> elements;
        private EPubMetadatas metaDatas;


        public EpubNavigationXhtmlWriter(string outputPath, IEnumerable<DocElement> elements, EPubMetadatas metadatas)
        {
            this.navHtmlFilePath = Path.Combine(outputPath, "OEBPS", "nav.xhtml");
            this.elements = elements;
            this.metaDatas = metadatas;
        }

        internal void WriteOut()
        {
            XElement doc = XElement.Load(navHtmlFilePath);

            // set title
            doc.XPathSelectElement("/xhtml:head/xhtml:title", nsmgr).Value = metaDatas.Title;

            // create section/chapter tree
            DocHeading currentHeading;
            
            var headings = new LinkedList<DocHeading>(elements.Where(h => (h as DocHeading) != null).Select(h => (DocHeading)h));

            XElement parentElement = new XElement(xhtml + "ol");
            doc.XPathSelectElement("/xhtml:body/xhtml:nav", nsmgr).Add(parentElement);

            // section loop
            while (headings.Count != 0 && (currentHeading = headings.First.Value) != null)
            {
                headings.RemoveFirst();
                var currentElement = new XElement(xhtml + "li", 
                    new XElement(xhtml + "a", 
                        new XAttribute("href", currentHeading.HeadingHtmlLink),
                        currentHeading.Title));

                parentElement.Add(currentElement);

                DocHeading nextHeading;
                if (headings.First == null) // reach to end
                    break;
                nextHeading = headings.First.Value;

                if (nextHeading.Level > currentHeading.Level)
                {
                    parentElement = new XElement(xhtml + "ol");
                    currentElement.Add(parentElement);
                }
                else if (nextHeading.Level < currentHeading.Level)
                    parentElement = parentElement.Parent.Parent;
            }

            using (FileStream fs = new FileStream(navHtmlFilePath, FileMode.Create, FileAccess.Write))
            using (StreamWriter sr = new StreamWriter(fs))
                doc.Save(sr);
        }

    }
}
